﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Monk_Monster_River
{
    class AcrossRiver
    {
        /// <summary>
        /// 所有过河动作
        /// </summary>
        public static readonly AcrossRiverAction[] Actions = new AcrossRiverAction[]
        {
            new AcrossRiverAction(ActionTag.ONE_MONSTER_GO, BoatState.REMOTE,-1,0),
            new AcrossRiverAction(ActionTag.TWO_MONSTER_GO, BoatState.REMOTE,-2,0 ),
            new AcrossRiverAction(ActionTag.ONE_MONK_GO, BoatState.REMOTE,0,-1),
            new AcrossRiverAction(ActionTag.TWO_MONK_GO, BoatState.REMOTE,0,-2),
            new AcrossRiverAction(ActionTag.ONE_MONSTER_ONE_MONK_GO, BoatState.REMOTE,-1,-1),
            new AcrossRiverAction(ActionTag.ONE_MONSTER_BACK, BoatState.LOCAL,1,0),
            new AcrossRiverAction(ActionTag.TWO_MONSTER_BACK, BoatState.LOCAL,2,0),
            new AcrossRiverAction(ActionTag.ONE_MONK_BACK, BoatState.LOCAL,0,1),
            new AcrossRiverAction(ActionTag.TWO_MONK_BACK, BoatState.LOCAL,0,2),
            new AcrossRiverAction(ActionTag.ONE_MONSTER_ONE_MONK_BACK, BoatState.LOCAL,1,1)
        };

        /// <summary>
        /// 使用递归算法实现状态树搜索
        /// </summary>
        public void SearchState(StateNode node)
        {
            if (node.IsFinalState())//检查是否过河成功(状态)
            {
                this.PrintResult(node);
                Console.WriteLine("Success to across the river!");
                Console.WriteLine();

                return;
            }

            foreach (var action in Actions)
                SearchStateOnNewAction(node, action);
            
        }

        private void SearchStateOnNewAction(StateNode node, AcrossRiverAction action)
        {
            var next = new StateNode(node.LocalMonster, node.LocalMonk, node.RemoteMonster, node.RemonteMonk);

            var result = node.MakeActionNewState(next, action);
            if (result)
            {
                next.Preview = node;
                if (next.IsValidState() && !IsProcessedState(next))
                    SearchState(next);
            }
        }



        private bool IsProcessedState(StateNode node)
        {
            var current = node;
            while (node.Preview != null)
            {
                //如果Preview存在就判断当前状态是否存在，存在返回true
                if (current.ToString().Equals(node.Preview.ToString()))
                    return true;

                node = node.Preview;//逐层查找
            }

            return false;
        }

        private void PrintResult(StateNode node)
        {
            Console.WriteLine(node);
            while (node.Preview != null)
            {
                Console.WriteLine(node.Preview);
                node = node.Preview;
            }
        }
    }
}
